package cn.yaxma.xmpp;

import android.graphics.Bitmap;
import android.util.Base64;

import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.chat.ChatManagerListener;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.iqregister.AccountManager;
import org.jivesoftware.smackx.vcardtemp.VCardManager;
import org.jivesoftware.smackx.vcardtemp.packet.VCard;

import java.io.ByteArrayOutputStream;

/**
 * Created by Yaxma on 2016/11/1.
 * Email：2678503498@qq.com
 */

public class XMPPService {

    public final String SERVICE_HOST = "192.168.1.136";
    public final String SERVICE_NAME = "192.168.1.136";
    public final int SERVICE_PORT = 5222;

    public AbstractXMPPConnection mXMPPTCPConnection;

    public static XMPPService xmppService;

    public static XMPPService getConnection() {
        if (xmppService == null) {
            synchronized (XMPPService.class) {
                if (xmppService == null) {
                    xmppService = new XMPPService();
                    xmppService.createConnection();
                }
            }
        }
        return xmppService;
    }

    private AbstractXMPPConnection createConnection() {
        XMPPTCPConnectionConfiguration connectionConfig = XMPPTCPConnectionConfiguration.builder()
                .setServiceName(SERVICE_NAME)
                .setHost(SERVICE_HOST)
                .setPort(SERVICE_PORT)
                .setConnectTimeout(5 * 1000)
                .setSendPresence(true) // 设置用户是否上线
                .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled) //不使用安全模式
                .build();
        mXMPPTCPConnection = new XMPPTCPConnection(connectionConfig);
        return mXMPPTCPConnection;
    }

    /**
     * 连接
     */
    public void connect() {
        Thread thread = new Thread(new Runnable() {
            @Override public void run() {
                String connectMsg;
                try {
                    if (mXMPPTCPConnection.isConnected()) {
                        connectMsg = "connect success";
                    } else {
                        mXMPPTCPConnection.connect();
                        connectMsg = mXMPPTCPConnection.isConnected() ? "connect success" : "connect failed";
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    connectMsg = "connect e = " + e.getMessage();
                }
                mXMPPListener.connect(connectMsg);
            }
        });
        thread.start();
    }

    /**
     * 断开连接
     */
    public void disconnect() {
        mXMPPTCPConnection.disconnect();
    }

    /**
     * 登录
     *
     * @param username 用户名
     * @param password 密码
     */
    public void login(final String username, final String password) {
        new Thread(new Runnable() {
            @Override public void run() {
                String loginMsg;
                try {
                    if (!mXMPPTCPConnection.isConnected())
                        mXMPPTCPConnection.connect();
                } catch (Exception e) {
                    e.printStackTrace();
                    mXMPPTCPConnection.disconnect();
                }
                if (mXMPPTCPConnection.isConnected()) {
                    if (!mXMPPTCPConnection.isAuthenticated()) {
                        try {
                            mXMPPTCPConnection.login(username, password);
                            loginMsg = mXMPPTCPConnection.isAuthenticated() ? "登录成功" : "登录失败";
                        } catch (Exception e) {
                            e.printStackTrace();
                            loginMsg = "登录异常=" + e.getMessage();
                        }
                    } else {
                        loginMsg = "登录成功";
                    }
                } else {
                    loginMsg = "connect failed";
                }
                mXMPPListener.login(loginMsg);
            }
        }).start();

        // 添加消息监听器
        ChatManager chatManager = ChatManager.getInstanceFor(mXMPPTCPConnection);
        chatManager.addChatListener(new ChatManagerListener() {
            @Override public void chatCreated(Chat chat, boolean createdLocally) {
                chat.addMessageListener(new ChatMessageListener() {
                    @Override public void processMessage(Chat chat, Message message) {
                        String content = message.getBody();
                        if (content != null) {
                            mXMPPListener.getMessage(message.getFrom(), content);
                        }
                    }
                });
            }
        });
    }

    /**
     * 注册
     *
     * @param username 用户名
     * @param password 密码
     */
    public void register(final String username, final String password) {
        new Thread(new Runnable() {
            @Override public void run() {
                String registerMsg;
                try {
                    if (!mXMPPTCPConnection.isConnected())
                        mXMPPTCPConnection.connect();
                } catch (Exception e) {
                    e.printStackTrace();
                    mXMPPTCPConnection.disconnect();
                }
                if (mXMPPTCPConnection.isConnected()) {
                    try {
                        AccountManager accountManager = AccountManager.getInstance(mXMPPTCPConnection);
                        if (accountManager.supportsAccountCreation()) {
                            accountManager.createAccount(username, password);
                            registerMsg = "注册成功";
                        } else {
                            registerMsg = "服务端不能注册";
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        registerMsg = "注册异常=" + e.getMessage();
                    }
                } else {
                    registerMsg = "connect failed";
                }
                mXMPPListener.register(registerMsg);
            }
        }).start();
    }

    /**
     * 修改密码
     *
     * @param newPassword 新密码
     */
    public void changePassword(final String newPassword) {
        new Thread(new Runnable() {
            @Override public void run() {
                String changePasswordMsg;
                try {
                    if (!mXMPPTCPConnection.isConnected())
                        mXMPPTCPConnection.connect();
                } catch (Exception e) {
                    e.printStackTrace();
                    mXMPPTCPConnection.disconnect();
                }
                if (mXMPPTCPConnection.isConnected()) {
                    try {
                        if (mXMPPTCPConnection.isAuthenticated()) {
                            AccountManager accountManager = AccountManager.getInstance(mXMPPTCPConnection);
                            accountManager.changePassword(newPassword);
                            changePasswordMsg = "修改密码成功";
                        } else {
                            changePasswordMsg = "请先登录";
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        changePasswordMsg = "修改密码异常=" + e.getMessage();
                    }
                } else {
                    changePasswordMsg = "connect failed";
                }
                mXMPPListener.changePassword(changePasswordMsg);
            }
        }).start();
    }

    /**
     * 修改头像
     *
     * @param bitmap
     */
    public void setAvatar(final Bitmap bitmap) {
        new Thread(new Runnable() {
            @Override public void run() {
                String setAvatarMsg;
                try {
                    if (mXMPPTCPConnection.isConnected())
                        mXMPPTCPConnection.connect();
                } catch (Exception e) {
                    e.printStackTrace();
                    mXMPPTCPConnection.disconnect();
                }
                if (mXMPPTCPConnection.isConnected()) {
                    try {
                        if (mXMPPTCPConnection.isAuthenticated()) {
                            VCardManager vCardManager = VCardManager.getInstanceFor(mXMPPTCPConnection);
                            VCard vCard = vCardManager.loadVCard();
                            byte[] bytes = bitmapToByte(bitmap);
                            String encodeImage = Base64.encodeToString(bytes, android.util.Base64.DEFAULT);
                            vCard.setAvatar(bytes);
                            vCardManager.saveVCard(vCard);
                            setAvatarMsg = "修改头像成功";
                        } else {
                            setAvatarMsg = "请先登录";
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        setAvatarMsg = "修改头像异常=" + e.getMessage();
                    }
                } else {
                    setAvatarMsg = "connect failed";
                }
                mXMPPListener.setAvatar(setAvatarMsg);
            }
        }).start();
    }

    private byte[] bitmapToByte(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        return baos.toByteArray();
    }

    public void sendMessage(String username, String msg) {
        if (!mXMPPTCPConnection.isConnected())
            connect();
        if (mXMPPTCPConnection.isConnected()) {
            try {
                if (mXMPPTCPConnection.isAuthenticated()) {
                    ChatManager chatManager = ChatManager.getInstanceFor(mXMPPTCPConnection);
                    String serviceName = mXMPPTCPConnection.getServiceName();
                    Chat chat = chatManager.createChat(username + "@" + serviceName);
                    chat.sendMessage(msg);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public XMPPListener mXMPPListener;

    public void setXMPPListener(XMPPListener listener) {
        mXMPPListener = listener;
    }

}
